﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
using System.Xml.Serialization;
using System.ComponentModel;
using ViewMaker.Core.Utils;

namespace ViewMaker.Core.Controls
{
    /// <summary>
    /// ユーザコントロールViewコントロール
    /// </summary>
    public class UserControlViewControl : HeaderViewControl
    {
        public new class Properties : HeaderViewControl.Properties
        {
            public const string TypeName = "TypeName";
        }

        /// <summary>
        /// ユーザコントロールのタイプ名
        /// </summary>
        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "TypeNameList")]
        [ViewProperty(ComboBoxViewControl.Properties.IsEditable, true)]
        public string TypeName { get; set; }

        [XmlIgnore]
        [Browsable(false)]
        public override bool CanOverrideWidth { get { return false; } }

        [XmlIgnore]
        [Browsable(false)]
        public override bool CanOverrideHeight { get { return false; } }

        [XmlIgnore]
        [Browsable(false)]
        public List<string> TypeNameList
        {
            get
            {
                return this.Item.GetBindingType().Assembly.GetExportedTypes()
                    .Where(x => typeof(System.Windows.Controls.UserControl).IsAssignableFrom(x))
                    .Select(x=>x.AssemblyQualifiedName).ToList();
            }
        }


        public UserControlViewControl()
        {
            ControlType = ViewControlType.UserControl;
            IsPanel = false;
        }

        public override List<XamlNode> CreateXaml(XamlNode parent)
        {
            var list = base.CreateXaml(parent);
            if (!string.IsNullOrEmpty(TypeName))
            {
                var cont = parent.CreateElement("ContentControl");   // UserControlにDataContextを指定すると基本となるパスがヘッダーとアイテムで異なるための対処
                cont.SetAttribute("HorizontalContentAlignment", LayoutHorizontalAlignment.Stretch.ToString());
                cont.SetAttribute("VerticalContentAlignment", LayoutVerticalAlignment.Stretch.ToString());

                var uc = cont.ParseElement(GetUcXaml());
                cont.AppendChild(uc);
                SetBindingAttribute(uc, "DataContext", Item.BindPath, true);
                ApplyBaseProperty(uc);
                uc.SetAttribute("IsEnabled", null);
                uc.SetAttribute("Visibility", null);
                if (!string.IsNullOrEmpty(IsEnabled)) SetBindingAttribute(cont, "IsEnabled", IsEnabled, true);
                if (!string.IsNullOrEmpty(IsVisibile)) SetBindingAttribute(cont, "Visibility", IsVisibile + ", Converter={StaticResource BooleanToVisibilityConverter}", true);
                cont.SetAttribute("Name", null);
                if (!string.IsNullOrWhiteSpace(Item.Name)) uc.SetAttribute("Name", Item.Name);
                list.Add(cont);
            }
            return list;
        }

        private string GetUcXaml()
        {
            if (string.IsNullOrEmpty(TypeName)) throw new NotSupportedException("TypeName is null or empty");
            string[] nsClassAsm = TypeName.Split(',');
            if (nsClassAsm.Length < 2) throw new NotSupportedException("TypeName is invalid format");
            string className = nsClassAsm[0].Split('.').Last().Trim();
            int len = nsClassAsm[0].Length - className.Length - 1;
            if (len < 0) len = 0;
            string ns = nsClassAsm[0].Substring(0, len).Trim();

            string asm = nsClassAsm[1].Trim();
            string ucXaml = "<uc:" + className + " xmlns:uc=\"clr-namespace:" + ns + ";assembly=" + asm + "\"/>";
            // Silverlight not support partial assembly name.
            //var ucType = Type.GetType(TypeName);
            //return "<uc:" + ucType.Name + " xmlns:uc=\"clr-namespace:" + ucType.Namespace + ";assembly=" + ucType.Assembly.FullName.Split(',')[0] + "\"/>";
            return ucXaml;
        }
    }

}
